#ifndef _IGLOBAL_H_
#define _IGLOBAL_H_

#include <ctime>
#include <BMap>
#include <BRange>
#include <BString>
#include <BLibrary>
#include <BReadWrite>
#include <BSocket>
#include <BScene>
#include <BDrag>
#include <BCursor>
#include <BStyle>
#include <BAudioInput>
#include <BAudioOutput>
#include <BApplication>
#include "IWindow.h"

using namespace BWE;

//"get" interface function name for .brw file
typedef BReadWrite* (*func_get)();

class bplugin
{
public:
	BString				ext;
	BHolder<BLibrary>	lib;
	BHolder<BReadWrite>	rw;
};

class SlotPack
{
public:
	SlotPack()
	{
		object = 0;
		signal = 0;
	}
	SlotPack(int signal, const BValue& value)
	{
		this->object = 0;
		this->signal = signal;
		this->value = value;
	}
	SlotPack(const BString& signal, const BValue& value)
	{
		this->signal = 0;
		this->object = 0;
		this->strsig = signal;
		this->value = value;
	}
	SlotPack(BObject* object, int signal, const BValue& value)
	{
		this->object = object;
		this->signal = signal;
		this->value = value;
	}
	SlotPack(BObject* object, const BString& signal, const BValue& value)
	{
		this->signal = 0;
		this->object = object;
		this->strsig = signal;
		this->value = value;
	}
	SlotPack(const SlotPack& other)
	{
		object = other.object;
		signal = other.signal;
		strsig = other.strsig;
		value = other.value;
	}

	inline bool operator == (const SlotPack& other) const
	{
		return object == other.object && signal == other.signal && strsig == other.strsig && value == other.value;
	}
	inline bool operator == (const BObject* obj) const
	{
		return object == obj;
	}

	BObject*		object;
	int				signal;
	BString			strsig;
	BValue			value;
};
typedef BArray<SlotPack>	SlotPackArray;

class SignalWait
{
public:
	SignalWait()
	{
		handle = 0;
		signal = 0;
		result = 0;
		timeout = 0.0;
	}
#ifdef linux
	pthread_cond_t cond;
	pthread_t handle;
#endif
#ifdef _WIN32
	HANDLE handle;
#endif
	double			timeout;
	int				signal;
	BString			strsig;
	bool*			result;
};
typedef BArray<SignalWait>	SignalWaitArray;

extern clock_t			app_tick;
extern bool				app_done;
extern int				app_code;
extern int 				app_realFrequency;
extern int				app_frequency;
extern double			app_lastRenderTime;
extern double			app_clickInterval;
#ifdef linux
#include <X11/Xlib.h>
extern pthread_t		app_handle;
extern Display*			app_display;
#endif
#ifdef _WIN32
extern HANDLE			app_handle;
#endif

extern BValue					app_clipBoard;
extern BString					app_libPath;
extern BArray<BString>			app_pluginPaths;
extern BArray<BString>			app_fontPaths;
extern BArray<BString>			app_dataPaths;

extern BHolder<BStyle>			app_style;
extern BList<IWindowHolder>		app_windows;
extern BList<BSocket*>			app_sockets;
extern BList<BScene*>			app_scenes;
extern BList<BAudioInput*>		app_audioInputs;
extern BList<BAudioOutput*>		app_audioOutputs;

extern BList<bplugin>			app_plugins;
extern BMap<BString, BString>	app_extAlias;

extern BMap<BObject*, SlotPackArray>	app_slotPackMap;
extern BMap<BObject*, SignalWaitArray>	app_SignalWaitMap;

bool App_InitGlobalMutex();
bool App_LockGlobalMutex();
bool App_UnlockGlobalMutex();

bool App_AttachWindow(BWidget* widget);
bool App_DetachWindow(BWidget* widget);
BWidget* App_MainWindow();

void App_CycleBegin();
void App_Event(IWindow* window = 0);
void App_Event(BDrag* drag);
void App_Update();
void App_Frame();
void App_CycleEnd();

#endif